unit KRK.Components.CustomizedActions.RichEdit.AlignFullyJustified;

interface

uses ExtActns;

type
  TRichEditAlignFullyJustified = class(TRichEditAction)
  private
    procedure SetFullyJustifiedAlignment(Target: TObject);
    function GetFullyJustifiedAlignment(Target: TObject): Boolean;
  public
    procedure ExecuteTarget(Target: TObject); override;
    procedure UpdateTarget(Target: TObject); override;
  end;

implementation

uses RichEdit
   , Windows
   , ComCtrls;

procedure InitParaFormat2(var aParaFormat2: TParaFormat2);
begin
  ZeroMemory(@aParaFormat2, SizeOf(TParaFormat2));
  aParaFormat2.cbSize := SizeOf(TParaFormat2);
end;

{ TRichEditAlignFullyJustified }

function TRichEditAlignFullyJustified.GetFullyJustifiedAlignment(Target: TObject): Boolean;
var
  Paragraph: TParaFormat2;
begin
  InitParaFormat2(Paragraph);

  if TCustomRichEdit(Target).HandleAllocated then
    SendMessage(TCustomRichEdit(Target).Handle, EM_GETPARAFORMAT, 0, LPARAM(@Paragraph));

  Result := Paragraph.wAlignment = $4;
end;

procedure TRichEditAlignFullyJustified.SetFullyJustifiedAlignment(Target: TObject);
var
  Paragraph: TParaFormat2;
begin
  InitParaFormat2(Paragraph);

  with Paragraph do
  begin
    dwMask := PFM_ALIGNMENT;
    wAlignment := $4; { Justificado }
  end;

  TCustomRichEdit(Target).HandleNeeded; { we REALLY need the handle for BiDi }

  if TCustomRichEdit(Target).HandleAllocated then
    SendMessage(TCustomRichEdit(Target).Handle, EM_SETPARAFORMAT, 0, LPARAM(@Paragraph));
end;

procedure TRichEditAlignFullyJustified.ExecuteTarget(Target: TObject);
begin
  inherited;
  if Target is TCustomRichEdit then
    SetFullyJustifiedAlignment(Target);
  Checked := True;
end;

procedure TRichEditAlignFullyJustified.UpdateTarget(Target: TObject);
begin
  inherited;
  Enabled := Target is TCustomRichEdit;
  Checked := Enabled and GetFullyJustifiedAlignment(Target);
end;

end.
